package keter.sec.xss.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.WritableByteChannel;

/**
 * Created by gulx@neusoft.com on 2020/10/2.
 */
@RestController
@RequestMapping("/download")
public class DownloadController {
    private static final Logger logger = LoggerFactory.getLogger(DownloadController.class);

    @GetMapping("/1")
    public void makeDownload1(HttpServletRequest request,
                                    HttpServletResponse response, String localFileUri) throws IOException {
        logger.info("method1 begin");
        request.setCharacterEncoding("UTF-8");
//        long fileLength = new java.io.File(localFileUri).length();
//		String contentType = "application/octet-stream";
        response.setContentType("application/octet-stream");
        response.setHeader("Content-disposition", "attachment; filename=haha");
//        response.setHeader("Content-Length", String.valueOf(fileLength));
		toDownload(response, "/opt/"+localFileUri);
    }

    @GetMapping("/2")
    public void makeDownload2(HttpServletRequest request,
                                    HttpServletResponse response, String localFileUri) throws IOException {
        logger.info("method2 begin");
        request.setCharacterEncoding("UTF-8");
//        long fileLength = new java.io.File(localFileUri).length();
        response.setContentType("application/octet-stream");
        response.setHeader("Content-disposition", "attachment; filename=haha");
//        response.setHeader("Content-Length", String.valueOf(fileLength));
        transferToResponse(response, "/opt/"+localFileUri);
    }

    private static void toDownload(HttpServletResponse response, String localFileUri) throws IOException {
        logger.info("stream begin");
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(localFileUri));
        BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());
        try {
            byte[] buff = new byte[512];
            int bytesRead;
            while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
                bos.write(buff, 0, bytesRead);
            }
            logger.info("stream end");
        } catch (IOException e) {
           e.printStackTrace();
        } finally{
            bis.close();
            bos.close();
        }
    }

    private static void transferToResponse(HttpServletResponse response, String from){
        logger.info("channel begin");
        try(FileChannel fromChannel = new FileInputStream(from).getChannel()) {
            WritableByteChannel outChannel = Channels.newChannel(response.getOutputStream());
            fromChannel.transferTo(0,fromChannel.size(),outChannel);
            logger.info("channel end");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
